/*
Copyright (C) 2008-2011 ForceMem (Siarhei Fedarenko)
GNU General Public License version 3 (GPLv3)
 */
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TranscriptionWriter
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        public static void InsertText(string val, TextBox textBox)
        {
            if (textBox == null) return;

            int start = textBox.SelectionStart;
            if (textBox.SelectionLength > 0)
                textBox.SelectedText = val;
            else
            {
                textBox.Text = textBox.Text.Insert(start, val);
            }
            if (val == "[]" || val == "//" || val == "()")
                textBox.SelectionStart = start + 1;
            else textBox.SelectionStart = start + val.Length;
            textBox.Select();
        }

        private void tx_KeyPress(object sender, KeyPressEventArgs e)
        {
            string val = this.keyBoardPhonetic.GetChatByKey(e.KeyChar);
            if (!string.IsNullOrEmpty(val))
            {
                InsertText(val, this.tx);
                e.Handled = true;
            }
        }

        #region Check
        private void tv1_BeforeCheck(object sender, TreeViewCancelEventArgs e)
        {
            e.Cancel = true;
            try
            {
                this.tv1.BeforeCheck -= new System.Windows.Forms.TreeViewCancelEventHandler(this.tv1_BeforeCheck);
                if (e.Node.Parent == null)
                {
                    e.Node.Checked = !e.Node.Checked;
                    if (e.Node.Checked)
                    {
                        if (e.Node.Tag is TreeNode)
                            ((TreeNode)e.Node.Tag).Checked = true;
                        else if (e.Node.Nodes.Count > 0)
                            e.Node.Nodes[0].Checked = true;
                    }
                    else
                    {
                        foreach (TreeNode tn in e.Node.Nodes)
                            if (tn.Checked)
                                tn.Checked = false;
                    }
                }
                else
                {
                    if (e.Node.Checked)
                    {
                        e.Node.Checked = e.Node.Parent.Checked = false;
                    }
                    else
                    {
                        if (e.Node.Parent != null)
                        {
                            foreach (TreeNode tn in e.Node.Parent.Nodes)
                            {
                                if (tn.Checked)
                                    tn.Checked = false;
                            }
                        }
                        e.Node.Parent.Checked = e.Node.Checked = true;
                        e.Node.Parent.Tag = e.Node; // for remember state
                    }
                }
            }
            finally
            {
                this.tv1.BeforeCheck += new System.Windows.Forms.TreeViewCancelEventHandler(this.tv1_BeforeCheck);
            }
            
            this.tx.Text = "/" + GetlTranscription() + "/";
        }

        string GetlTranscription()
        {
            string ret = "";
            foreach (TreeNode tnRoot in this.tv1.Nodes)
            { 
                if( tnRoot.Checked )
                    foreach (TreeNode tnTrans in tnRoot.Nodes )
                        if (tnTrans.Checked)
                        {
                            ret += tnTrans.Tag.ToString();
                            break;
                        }
            }
            return ret;
        }        
        #endregion

        #region MenuItem s
        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new AboutForm()).ShowDialog();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.tx.SelectedText))
                Clipboard.SetText(this.tx.Text);
            else
                Clipboard.SetText(this.tx.SelectedText);
        }

        private void cutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            copyToolStripMenuItem_Click(null, null);
            if (string.IsNullOrEmpty(this.tx.SelectedText))
                this.tx.Text = "";
            else
                this.tx.SelectedText = "";
        } 

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.ActiveControl is TextBox)
            {
                ((TextBox)this.ActiveControl).SelectAll();
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            InsertText(Clipboard.GetText(), this.tx);
        }        
        
        private void editToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            this.cutToolStripMenuItem.Enabled = 
            this.copyToolStripMenuItem.Enabled = 
            this.selectAllToolStripMenuItem.Enabled = !string.IsNullOrEmpty(this.tx.Text);
            this.pasteToolStripMenuItem.Enabled = !string.IsNullOrEmpty(Clipboard.GetText());
        }

        private void customizeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            customizeToolStripMenuItem.Checked = !customizeToolStripMenuItem.Checked;
            optionsToolStripMenuItem.Checked = !customizeToolStripMenuItem.Checked;
        }

        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            optionsToolStripMenuItem.Checked = !optionsToolStripMenuItem.Checked;
            customizeToolStripMenuItem.Checked = !optionsToolStripMenuItem.Checked;
        }
        #endregion

        private void tx_KeyDown(object sender, KeyEventArgs e)
        {
            if( e.KeyData == (Keys.ShiftKey | Keys.Shift) )
            {
                this.keyBoardPhonetic.SwitchShift();
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            if (this.LoadRules())
            {
                this.txOriginal.Text = "Sample";
                this.txOriginal_TextChanged(null, null);
                if (this.tv1.Nodes[0].Nodes.Count > 4)
                    this.tv1.Nodes[0].Nodes[3].Checked = true;
                if (this.tv1.Nodes[1].Nodes.Count > 7)
                    this.tv1.Nodes[1].Nodes[6].Checked = true;
                this.tv1.Nodes[6].Checked = false;
                this.tx.Text = "/" + GetlTranscription() + "/";
                // for best appearence
                this.tv1.CollapseAll();
                this.tv1.Nodes[0].Expand();
            }
            // else MessageBox
        }

        private void txOriginal_TextChanged(object sender, EventArgs e)
        {
            try
            {
                this.tv1.BeginUpdate();
                this.tv1.BeforeCheck -= new System.Windows.Forms.TreeViewCancelEventHandler(this.tv1_BeforeCheck);

                this.tv1.Nodes.Clear();
                string word = txOriginal.Text.ToLower();
                Hashtable multipleKeys = new Hashtable();
                foreach (string key in this.keys.Keys)
                    if (key.Length > 1 && word.IndexOf(key) != -1 && !multipleKeys.Contains(word.IndexOf(key)))
                        multipleKeys.Add(word.IndexOf(key), this.keys[key]);
                int iForMultiple = -1;
                foreach (char c in word)
                {
                    SymbolKey key = keys[c.ToString()] as SymbolKey;
                    if (key != null)
                    {
                        TreeNode tn = AddNodeByRules(key);
                        // only for key where Key.Length == 1
                        tn.Checked = true;
                        if (tn.Tag is TreeNode) 
                            ((TreeNode)tn.Tag).Checked = true;
                        else tn.Nodes[0].Checked = true;
                    }
                    else this.tv1.Nodes.Add("?");
                    SymbolKey multipleKey = multipleKeys[++iForMultiple] as SymbolKey;
                    if (multipleKey != null)
                    {
                        AddNodeByRules(multipleKey);
                    }
                }
            }
            finally
            {
                if (this.tv1.Nodes.Count > 0)
                    this.tv1.SelectedNode = this.tv1.Nodes[0];
                this.tv1.ExpandAll();
                this.tv1.EndUpdate();
                this.tv1.BeforeCheck += new System.Windows.Forms.TreeViewCancelEventHandler(this.tv1_BeforeCheck);
            }
            this.tx.Text = "/" + GetlTranscription() + "/";
        }

        private TreeNode AddNodeByRules(SymbolKey key)
        {
            TreeNode tn = this.tv1.Nodes.Add(key.Key);
            foreach (Rule r in key)
            {
                TreeNode nodeRule = tn.Nodes.Add(r.ToString());
                nodeRule.Tag = r.Transcript;
                if (r == key.DefaultRule)
                {
                    tn.Tag = nodeRule;
                }
            }
            return tn;
        }

        Hashtable keys = new Hashtable();

        string tempDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\TranscriptionWriter\\";
        readonly string FileName = "EnglishOrthographyFromWikipedia.rtf";

        #region GetRules
	    bool LoadRules()
        {
            RichTextBox tx = new RichTextBox();
            string _fileName = FileName;
            if (!File.Exists(_fileName))
                _fileName = tempDir + FileName;
            if (!File.Exists(_fileName))
            {
                if (!ShowLisenceAgreement())
                {
                    Application.Exit();
                    return false;
                }
                Directory.CreateDirectory(tempDir);
                string s = TranscriptionWriter.Properties.Resources.EnglishOrthographyFromWikipedia;
//                TextWriter stringWriter = new StringWriter();
                using (TextWriter streamWriter = new StreamWriter(_fileName))
                {
                    streamWriter.Write(s);
                }
            }

            tx.LoadFile(_fileName);
            foreach (string line in tx.Lines)
            {
                if (string.IsNullOrEmpty(line)) continue;
                string keysRaw = line.Split('\t')[1];
                keysRaw = keysRaw.Replace("-", "");
                for (int i = 0; i < keysRaw.Split(',').Length; ++i)
                {
                    string keyName = keysRaw.Split(',')[i];
                    string realKey = keyName;
                    string ruleDescription = line.Split('\t')[2];
                    string example = line.Split('\t')[3].Split(',')[i].Trim();
                    if (keyName.Split('(').Length > 1)
                    {
                        realKey = keyName.Split('(')[0];
                        ruleDescription += keyName.Substring(realKey.Length).Trim();
                    }
                    else if (keyName.IndexOf("..") != -1)
                    {
                        realKey = keyName.Substring(0, keyName.IndexOf(".."));
                        ruleDescription += keyName;
                    }
                    #region key
                    realKey = realKey.Trim();
                    SymbolKey key = keys[realKey] as SymbolKey;
                    if (key == null)
                    {
                        key = new SymbolKey(realKey);
                        keys.Add(realKey, key);
                    }

                    #endregion
                    Rule rule = new Rule(line.Split('\t')[0], ruleDescription, example);
                    key.AddRule(rule);
                }
            }
            return keys.Count > 0;

            //int ii = -1;
            //SymbolKey[] _SymbolKeys = new SymbolKey[keys.Count];
            //foreach(DictionaryEntry sk in keys)
            //    _SymbolKeys[++ii] = (SymbolKey)sk.Value;
            //Array.Sort(_SymbolKeys);
            //string tabs = "\t\t\t\t\t\t";
            //foreach (SymbolKey k in _SymbolKeys)
            //{
            //    foreach (Rule r in k)
            //    {
            //        Console.WriteLine("Key: " + k.Key + tabs + " Trans: " + r.Transcript + tabs + " Descr: " + r.RuleDescr + tabs + " Exampl: " + r.Example);
            //    }
            //}
        }

        private bool ShowLisenceAgreement()
        {
            AboutForm frm = new AboutForm();
            frm.cbIAgree.Visible = true;
            return frm.ShowDialog() == DialogResult.OK;
        } 
	    #endregion    

        private void miRules_Click(object sender, EventArgs e)
        {
            string _fileName = FileName;
            if (!File.Exists(_fileName))
                _fileName = tempDir + FileName;
            if (File.Exists(_fileName))
                System.Diagnostics.Process.Start("wordpad", "\"" + tempDir + FileName + "\"");
        }
    }
}